/* 抽象工厂模式
抽象工厂模式可以向客户端提供一个接口，使客户端在不必指定产品的具体的情况下，创建多个产品族中的产品对象
工厂方法模式针对的是同一类或同等级产品,而抽象工厂模式针对的是多种类的产品设计
系统中有多个产品族,每个具体工厂负责创建同一族但属于不同产品等级(产品种类)的产品
产品族是一组相关或相互依赖的对象
系统一次只能消费某一族产品，即相同产品族的产品是一起被使用的
当系统需要新增一个产品族时，只需要增加新的工厂类即可，无需修改源代码; 但是如果需要产品族中增加一个新种类的产品时,则所有的工厂类都需要修改
*/
/* 组成角色
抽象工厂: 提供了创建产品的接口,包含多个创建产品的方法,即包含多个类似创建产品的方法
具体工厂: 实现抽象工厂定义的接口,完成某个具体产品的创建
抽象产品: 抽象产品定义,一般有多少抽象产品,抽象工厂中就包含多少个创建产品的方法
具体产品: 抽象产品的实现类
*/

export {}

abstract class AmericanCoffee{
}

abstract class LatteCoffee{
}

abstract class CappuccinoCoffee{
}


class StarBucksAmericanCoffee extends AmericanCoffee{}
class LuckinAmericanCoffee extends AmericanCoffee{}
class StartBucksLatteCoffee extends LatteCoffee{}
class LuckinLatteCoffee extends LatteCoffee{}
class StarBucksCappuccinoCoffee extends CappuccinoCoffee{}
class LuckinCappuccinoCoffee extends CappuccinoCoffee{}

abstract class CafeFactory {
  abstract createAmericanCoffee(): AmericanCoffee;
  abstract createLatteCoffee(): LatteCoffee;
  abstract createCappuccinoCoffee(): CappuccinoCoffee;
}

class StarBucksCafeFactory extends CafeFactory {
  createAmericanCoffee(): AmericanCoffee {
    return new StarBucksAmericanCoffee()
  }
  createCappuccinoCoffee(): CappuccinoCoffee {
    return new StarBucksCappuccinoCoffee()
  }
  createLatteCoffee(): LatteCoffee {
    return new StartBucksLatteCoffee()
  }
}

class LuckinCafeFactory extends CafeFactory {
  createAmericanCoffee(): AmericanCoffee {
    return new LuckinAmericanCoffee()
  }
  createCappuccinoCoffee(): CappuccinoCoffee {
    return new LuckinCappuccinoCoffee()
  }
  createLatteCoffee(): LatteCoffee {
    return new LuckinLatteCoffee()
  }
}



const starbucksCafeFactory = new StarBucksCafeFactory()
console.log('starbucksCafeFactory.createAmericanCoffee():',starbucksCafeFactory.createAmericanCoffee())
console.log('starbucksCafeFactory.createCappuccinoCoffee():',starbucksCafeFactory.createCappuccinoCoffee())
console.log('starbucksCafeFactory.createLatteCoffee():',starbucksCafeFactory.createLatteCoffee())

const luckinCafeFactory = new LuckinCafeFactory()
console.log('luckinCafeFactory.createAmericanCoffee():',luckinCafeFactory.createAmericanCoffee())
console.log('luckinCafeFactory.createCappuccinoCoffee():',luckinCafeFactory.createCappuccinoCoffee())
console.log('luckinCafeFactory.createLatteCoffee():',luckinCafeFactory.createLatteCoffee())


//当系统需要新增一个产品族时,只需要增加新的工厂类即可,无需修改源代码; 但是如果需要产品族中增加一个新种类的产品时,则所有的工厂类都需要修改
